//
// Created by hkkzzxz on 24-9-1.
//

#include <json/json.h>

#include "AdminService.h"
#include "RedisDatabaseModel.h"
#include "MySQLDatabaseModel.h"
#include "EmployeeAttendanceRules.h"
#include "EmployeeInformation.h"
#include "EmployeeAllAttendance.h"

bool AdminService::addEmployee(const std::string &id, const std::string &name, const std::string &phone_number) {
    // 向redis缓存数据，员工注册时做判断
    Json::Value redisValue;
    redisValue["name"] = name;
    redisValue["phone_number"] = phone_number;
    auto redisDatabaseModel = std::make_unique<RedisDatabaseModel>();
    if (!redisDatabaseModel->set(id, redisValue.toStyledString())) {
        return false;
    }
    // 读取全体人员的考勤时间
    std::string morningStartTime = redisDatabaseModel->get("morning_start_time");
    std::string eveningEndTime = redisDatabaseModel->get("evening_end_time");
    if (morningStartTime.empty() || eveningEndTime.empty()) {
        return false;
    }

    // 向user表先插入数据
    std::string insert = "INSERT INTO user (id, name, identity) VALUES (?, ?, ?)";
    std::vector<std::string> params = {id, name, "employee"};
    auto mysqlDatabaseModel = std::make_unique<MySQLDatabaseModel>();
    if (!mysqlDatabaseModel->insert(insert, params)) {
        return false;
    }

    // 向attendance_settings表写入考勤规则
    insert = "INSERT INTO attendance_settings (employee_id, morning_start_time, evening_end_time) VALUES (?, ?, ?)";
    params = {id, morningStartTime, eveningEndTime};
    if (mysqlDatabaseModel->insert(insert, params)) {
        return true;
    }
    return false;
}

bool AdminService::setAllAttendanceRules(const std::string &morningStartTime, const std::string &eveningEndTime) {
    // 更新redis里面设置的时间
    auto redisDatabaseModel = std::make_unique<RedisDatabaseModel>();
    if (!redisDatabaseModel->set("morning_start_time", morningStartTime)
        || !redisDatabaseModel->set("evening_end_time", eveningEndTime)) {
        return false;
    }
    // 设置MySQL考勤表所有人的考勤规则
    std::string update = "UPDATE attendance_settings SET morning_start_time = ?, evening_end_time = ?";
    std::vector<std::string> params = {morningStartTime, eveningEndTime};
    auto mysqlDatabaseModel = std::make_unique<MySQLDatabaseModel>();
    if (mysqlDatabaseModel->update(update, params)) {
        return true;
    }
    return false;
}

bool AdminService::setAttendanceRules(const std::string &id, const std::string &morningStartTime,
                                      const std::string &eveningEndTime) {
    // 在MySQL数据库里面修改个人的考勤规则
    std::string update = "UPDATE attendance_settings SET morning_start_time = ?, evening_end_time = ? WHERE employee_id = ?";
    std::vector<std::string> params = {morningStartTime, eveningEndTime, id};
    auto mysqlDatabaseModel = std::make_unique<MySQLDatabaseModel>();
    if (mysqlDatabaseModel->update(update, params)) {
        return true;
    }
    return false;
}

bool AdminService::deleteEmployee(const std::string &id, const std::string &name) {
    // 先判断Redis里面是否存在这个键值对
    auto redisDatabaseModel = std::make_unique<RedisDatabaseModel>();
    if (redisDatabaseModel->exists(id)) {
        // 存在则删除
        redisDatabaseModel->del(id);
    }
    // 删除表中关于员工的所有数据，数据库设计时做了级联删除
    std::string update = "DELETE FROM user WHERE id = ? AND name = ?";
    std::vector<std::string> params = {id, name};
    auto mysqlDatabaseModel = std::make_unique<MySQLDatabaseModel>();
    if (mysqlDatabaseModel->update(update, params)) {
        return true;
    }
    return false;
}

std::string AdminService::checkAttendanceRules() {
    // 连表查询，从MySQL中attendance_settings考勤规则，并在user表里面找到对应姓名
    std::string query = "SELECT attendance_settings.employee_id, attendance_settings.morning_start_time, attendance_settings.evening_end_time, user.name\n"
                        "FROM attendance_settings INNER JOIN user ON attendance_settings.employee_id = user.id";
    std::vector<std::string> params = {};
    auto mysqlDatabaseModel = std::make_unique<MySQLDatabaseModel>();
    auto employeeAttendanceRules = mysqlDatabaseModel->queryModel<EmployeeAttendanceRules>(query, params);
    if (employeeAttendanceRules.empty()) {
        return "";
    }

    // 循环读取为数组
    Json::Value data;
    for (auto &i: employeeAttendanceRules) {
        Json::Value temp;
        temp["id"] = i->getId();
        temp["name"] = i->getName();
        temp["morning_start_time"] = i->getMorningStartTime();
        temp["evening_end_time"] = i->getEveningEndTime();
        data.append(temp);
    }
    return data.toStyledString();
}

std::string AdminService::employeeInformation() {
    // 连表查询，从MySQL中user表中找到工号，姓名，并在employee表里面找到对应电话号码
    std::string query = "SELECT u.id, u.name, e.phone_number FROM user u\n"
                        "LEFT JOIN employee e ON u.id = e.id\n"
                        "WHERE u.identity = 'employee'";
    std::vector<std::string> params = {};
    auto mysqlDatabaseModel = std::make_unique<MySQLDatabaseModel>();
    auto employeeInformation = mysqlDatabaseModel->queryModel<EmployeeInformation>(query, params);
    if (employeeInformation.empty()) {
        return "";
    }

    Json::Value data;
    for (auto &i: employeeInformation) {
        Json::Value temp;
        temp["id"] = i->getId();
        temp["name"] = i->getName();
        temp["phone_number"] = i->getPhoneNumber();
        data.append(temp);
    }
    return data.toStyledString();
}

std::string AdminService::checkAttendance() {
    // 从MySQL数据库中查询出元素
    std::string query = "SELECT ar.employee_id, ar.check_in_time, ar.check_out_time, ar.date, ar.late,\n"
                        "    ar.leave_early, u.name, e.phone_number\n"
                        "FROM  attendance_records ar\n"
                        "LEFT JOIN  user u ON ar.employee_id = u.id\n"
                        "LEFT JOIN employee e ON ar.employee_id = e.id";
    std::vector<std::string> params = {};
    auto mysqlDatabaseModel = std::make_unique<MySQLDatabaseModel>();
    auto employeeAllAttendance = mysqlDatabaseModel->queryModel<EmployeeAllAttendance>(query, params);
    if (employeeAllAttendance.empty()) {
        return "";
    }
    Json::Value data;
    for (auto &i: employeeAllAttendance) {
        Json::Value temp;
        temp["id"] = i->getId();
        temp["name"] = i->getName();
        temp["phone_number"] = i->getPhoneNumber();
        temp["date"] = i->getDate();
        temp["check_in_time"] = i->getCheckInTime();
        temp["check_out_time"] = i->getCheckOutTime();
        if (i->isLate() && !i->isLeaveEarly()) {
            temp["status"] = "late";
        } else if (!i->isLate() && i->isLeaveEarly()) {
            temp["status"] = "leave early";
        } else if (i->isLate() && i->isLeaveEarly()) {
            temp["status"] = "late and leave early";
        } else {
            temp["status"] = "normal";
        }
        data.append(temp);
    }
    return data.toStyledString();
}

std::string AdminService::exportReport() {
    std::stringstream csv;
    // 写入CSV标题行
    csv << "id,name,phone_number,date,check_in_time,check_out_time,status\n";

    // 从MySQL数据库中查询出元素
    std::string query = "SELECT ar.employee_id, ar.check_in_time, ar.check_out_time, ar.date, ar.late,\n"
                        "    ar.leave_early, u.name, e.phone_number\n"
                        "FROM  attendance_records ar\n"
                        "LEFT JOIN  user u ON ar.employee_id = u.id\n"
                        "LEFT JOIN employee e ON ar.employee_id = e.id";
    std::vector<std::string> params = {};
    auto mysqlDatabaseModel = std::make_unique<MySQLDatabaseModel>();
    auto employeeAllAttendance = mysqlDatabaseModel->queryModel<EmployeeAllAttendance>(query, params);
    if (employeeAllAttendance.empty()) {
        return "";
    }

    // 遍历查询结果并写入CSV
    for (const auto &i: employeeAllAttendance) {
        csv << i->getId() << ",";
        csv << "\"" << i->getName() << "\",";
        csv << "\"" << i->getPhoneNumber() << "\",";
        csv << "\"" << i->getDate() << "\",";
        csv << "\"" << i->getCheckInTime() << "\",";
        csv << "\"" << i->getCheckOutTime() << "\",";

        // 确定状态
        std::string status;
        if (i->isLate() && !i->isLeaveEarly()) {
            status = "late";
        } else if (!i->isLate() && i->isLeaveEarly()) {
            status = "leave early";
        } else if (i->isLate() && i->isLeaveEarly()) {
            status = "late and leave early";
        } else {
            status = "normal";
        }
        csv << "\"" << status << "\"\n";
    }

    return csv.str();
}

bool AdminService::synchronizeData(std::string &data) {
    std::string update = "TRUNCATE TABLE attendance_records";
    std::vector<std::string> params = {};
    auto mysqlDatabaseModel = std::make_unique<MySQLDatabaseModel>();
    mysqlDatabaseModel->update(update, params);

    std::istringstream csvStream(data);
    std::string line;
    // 跳过标题行
    std::getline(csvStream, line);

    std::string insert = "INSERT INTO attendance_records (employee_id, check_in_time, check_out_time, date, late, leave_early) VALUES (?, ?, ?, ?, ?, ?)";

    while (std::getline(csvStream, line)) {
        std::vector<std::string> fields;
        std::stringstream lineStream(line);
        std::string cell;
        while (std::getline(lineStream, cell, ',')) {
            // 移除引号
            cell.erase(std::remove(cell.begin(), cell.end(), '\"'), cell.end());
            fields.push_back(cell);
        }

        // 解析字段
        std::string employee_id = fields[0];
        std::string check_in_time = fields[4];
        std::string check_out_time = fields[5];
        std::string date = fields[3];
        bool late = fields[6].find("late") != std::string::npos;
        bool leave_early = fields[6].find("leave early") != std::string::npos;

        // 构建参数
        params = {employee_id, check_in_time, check_out_time, date, late ? "1" : "0",
                  leave_early ? "1" : "0"};

        // 插入数据
        if (!mysqlDatabaseModel->insert(insert, params)) {
            return false;
        }
    }
    return true;
}
